/**
 * @file 事件处理工具
 * @description 提供类型安全的事件发射器和相关工具
 * @author 黄敏
 * @version 1.0.0
 * @since 2025-08-12
 */

import { EventEmitter } from 'node:events'

// ==================== 类型定义 ====================

type EventMap = {
  [K: string]: (...args: any[]) => any // 中间用 `any[]` 类型推断用，不传递到外部
}

// 如果你想要更严格的类型安全，可以使用这个替代方案：
// type EventMap = {
//   [K: string]: (...args: unknown[]) => unknown
// }

type EventName<T extends EventMap> = keyof T & string
type Listener<T extends EventMap, K extends EventName<T>> = T[K] extends (...args: infer A) => void
  ? (...args: A) => void
  : never

// ==================== 类型安全的事件发射器 ====================

/**
 * 类型安全的事件发射器
 * @description 扩展 Node.js EventEmitter，提供完整的 TypeScript 类型支持
 * @template T - 事件映射类型
 * @example
 * ```ts
 * type MyEvents = {
 *   'data': (data: string) => void
 *   'error': (error: Error) => void
 * }
 *
 * const emitter = new TypedEventEmitter<MyEvents>()
 * emitter.on('data', (data) => console.log(data)) // data 自动推断为 string 类型
 * emitter.emit('data', 'hello world')
 * ```
 */
export class TypedEventEmitter<T extends EventMap> extends EventEmitter {
  override on<K extends EventName<T>>(event: K, listener: Listener<T, K>): this {
    return super.on(event, listener)
  }

  override once<K extends EventName<T>>(event: K, listener: Listener<T, K>): this {
    return super.once(event, listener)
  }

  override off<K extends EventName<T>>(event: K, listener: Listener<T, K>): this {
    return super.off(event, listener)
  }

  override emit<K extends EventName<T>>(event: K, ...args: Parameters<T[K]>): boolean {
    return super.emit(event, ...args)
  }

  override addListener<K extends EventName<T>>(event: K, listener: Listener<T, K>): this {
    return super.addListener(event, listener)
  }

  override removeListener<K extends EventName<T>>(event: K, listener: Listener<T, K>): this {
    return super.removeListener(event, listener)
  }

  override removeAllListeners<K extends EventName<T>>(event?: K): this {
    // 当没有传入参数时，调用不带参数的 super.removeAllListeners()
    if (arguments.length === 0) {
      return super.removeAllListeners()
    }
    return super.removeAllListeners(event)
  }

  override listeners<K extends EventName<T>>(event: K): Listener<T, K>[] {
    return super.listeners(event) as Listener<T, K>[]
  }

  override rawListeners<K extends EventName<T>>(event: K): Listener<T, K>[] {
    return super.rawListeners(event) as Listener<T, K>[]
  }

  override listenerCount<K extends EventName<T>>(event: K): number {
    return super.listenerCount(event)
  }

  override prependListener<K extends EventName<T>>(event: K, listener: Listener<T, K>): this {
    return super.prependListener(event, listener)
  }

  override prependOnceListener<K extends EventName<T>>(event: K, listener: Listener<T, K>): this {
    return super.prependOnceListener(event, listener)
  }
}

// ==================== 导出 ====================

// 导出类型
export type { EventMap, EventName, Listener }
